﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lacrima.Framework.Infrastructure
{
    public static class TransferUtility
    {
        /// <summary>
        /// 英尺的进率，1英尺(ft)=0.3048米(m)
        /// </summary>
        public const double FootRate = 0.3048d;

        /// <summary>
        /// 公里转化为节需要乘以这个数值
        /// </summary>
        public const double KnotsRate = 1.852d;

        /// <summary>
        /// 米转换为英尺
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>System.Double.</returns>
        public static double MeterToFoot(double source)
        {
            return source / FootRate;
        }

        public static double MeterToFoot(string source)
        {
            if (!string.IsNullOrEmpty(source))
            {
                return MeterToFoot(double.Parse(source));
            }
            else
            {
                return Double.NaN;
            }
        }

        public static double FootToMeter(double source)
        {
            return (source * FootRate);
        }

        public static double FootToMeter(string source)
        {
            if (!string.IsNullOrEmpty(source))
            {
                return FootToMeter(double.Parse(source));
            }
            else
            {
                return Double.NaN;
            }
        }

        /// <summary>
        /// 千米转换为米
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>System.Double.</returns>
        public static double KiloMeterToKnots(double source, int digitalSize = int.MinValue)
        {
            if (digitalSize == int.MinValue)
            {
                return source / KnotsRate;
            }
            else
            {
                return Math.Round(source / KnotsRate, digitalSize);
            }
        }

        /// <summary>
        /// 千米转换为米
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>System.Double.</returns>
        public static double KiloMeterToMeter(double source, int digitalSize = int.MinValue)
        {
            if (digitalSize == int.MinValue)
            {
                return source * 1000;
            }
            else
            {
                return Math.Round(source * 1000, digitalSize);
            }
        }

        public static double KiloMeterToMeter(string source, int digitalSize = int.MinValue)
        {
            if (!string.IsNullOrEmpty(source))
            {
                return KiloMeterToMeter(double.Parse(source), digitalSize);
            }
            else
            {
                return Double.NaN;
            }
        }

        /// <summary>
        /// 千米转换为英尺
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>System.Double.</returns>
        public static double KiloMeterToFoot(double source, int digitalSize = int.MinValue)
        {
            if (digitalSize == int.MinValue)
            {
                return source * 1000 / FootRate;
            }
            else
            {
                return Math.Round(source * 1000 / FootRate, digitalSize);
            }
        }

        public static double KiloMeterToFoot(string source, int digitalSize = int.MinValue)
        {
            if (!string.IsNullOrEmpty(source))
            {
                return KiloMeterToFoot(double.Parse(source), digitalSize);
            }
            else
            {
                return Double.NaN;
            }
        }

        /// <summary>
        /// 英尺转换为千米
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>System.Double.</returns>
        public static double FootToKiloMeter(double source)
        {
            return (source * FootRate / 1000);
        }

        public static double FootToKiloMeter(string source)
        {
            if (!string.IsNullOrEmpty(source))
            {
                return FootToKiloMeter(double.Parse(source));
            }
            else
            {
                return Double.NaN;
            }
        }

        /// <summary>
        /// 获取向左偏移两位的数值
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>System.Double.</returns>
        public static double GetLeftTwoDecimalOffset(double source)
        {
            if (!double.IsNaN(source)
                && !double.IsNegativeInfinity(source)
                && !double.IsPositiveInfinity(source))
            {
                return (source * 100 % 100);
            }
            return double.NaN;
        }


        /// <summary>
        /// 坐标转换，将十进制度转换为度时分秒的形式
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>System.String.</returns>
        public static string CoordinateTransform(double source)
        {
            if (source < (double.Epsilon * -1))
            {
                source *= -1;
            }
            double degree = source;
            double minute = GetLeftTwoDecimalOffset(degree) * 60 / 100;
            double second = GetLeftTwoDecimalOffset(minute) * 60;
            string coordinate = string.Format("{0:00}{1:00}{2:0000}", (int)degree, (int)minute, Math.Round(second, 0));
            return coordinate;
        }

        /// <summary>
        /// 将十进制纬度转换为坐标制纬度
        /// 方法参照：http://blog.sina.com.cn/s/blog_7b0807af0101lh3n.html
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>System.String.</returns>
        public static string ToLatitude(double source)
        {
            bool direction = source > double.Epsilon;
            string magneticPole = direction ? "N" : "S";
            string latitude = string.Format("{0}{1}", magneticPole, CoordinateTransform(source));
            return latitude;
        }

        /// <summary>
        /// 转换为纬度
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>System.String.</returns>
        public static string ToLatitude(string source)
        {
            if (!string.IsNullOrEmpty(source))
            {
                double target = double.Parse(source);
                bool direction = target > double.Epsilon;
                string magneticPole = direction ? "N" : "S";
                string latitude = string.Format("{0}{1}", magneticPole, CoordinateTransform(target));
                return latitude;
            }
            else
            {
                return double.NaN.ToString();
            }
        }

        /// <summary>
        /// 将十进制经度转换为坐标制经度
        /// 方法参照：http://blog.sina.com.cn/s/blog_7b0807af0101lh3n.html
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>System.String.</returns>
        public static string ToLongitude(double source)
        {
            bool direction = source > double.Epsilon;
            string flag = direction ? "E" : "W";
            string longitude = string.Format("{0}{1}", flag, CoordinateTransform(source));
            return longitude;
        }

        public static string ToLongitude(string source)
        {
            if (!string.IsNullOrEmpty(source))
            {
                double target = double.Parse(source);
                bool direction = target > double.Epsilon;
                string flag = direction ? "E" : "W";
                string longitude = string.Format("{0}{1}", flag, CoordinateTransform(target));
                return longitude;
            }
            else
            {
                return double.NaN.ToString();
            }
        }

        /// <summary>
        /// Gets the padding magnetic variation.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>System.Double.</returns>
        public static double GetPaddingMagneticVariation(double source)
        {
            if (!double.IsNaN(source) && source < (double.Epsilon * -1))
            {
                source *= -1;
            }
            return source * 10;
        }

        /// <summary>
        /// 磁偏角转换方法
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>System.String.</returns>
        public static string MagneticVariationTransform(double source)
        {
            bool direction = source > double.Epsilon;
            string flag = direction ? "E" : "W";
            string magneticVariation = string.Format("{0}{1}", flag, GetPaddingMagneticVariation(source).ToString().PadLeft(4, '0'));
            return magneticVariation;
        }

        public static string CreateRunwayDirectionIdentitifer(string runwayIdentifier)
        {
            return string.IsNullOrEmpty(runwayIdentifier) ? string.Empty : string.Format("RW{0}", runwayIdentifier);
        }

        public static string PadProcedureSequenceNumber(string sequenceNumber)
        {
            return string.IsNullOrEmpty(sequenceNumber) ? string.Empty : string.Format("{0}0", sequenceNumber);
        }
    }
}
